package com.ehotting.mqbd.zw.netty.netty;


import com.ehotting.eaf.core.utils.ByteUtils;
import com.ehotting.mqbd.zw.api.constants.ActionConstants;
import com.ehotting.mqbd.zw.api.domain.netty.ShakeHandReq;
import com.ehotting.mqbd.zw.api.domain.netty.ZwCommPacket;
import com.ehotting.mqbd.zw.api.domain.netty.ZwCommPacketHead;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class ZwDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf buf, List<Object> out) {

        int readableBytesLen = buf.readableBytes();
        log.info("buf.readableBytesLen():{}", readableBytesLen);
        if (readableBytesLen<8){
            // 最小长度是握手指令
            log.error("readableBytesLen[{}]< min len is error,return.",readableBytesLen);
            return;
        }
        buf.markReaderIndex();

        byte[] bytes = new byte[ShakeHandReq.content.length];
        buf.readBytes(bytes);
//        log.info("buf.readBytes(bytes):{}", ByteUtils.byteToHex(bytes));
        if (ByteUtils.compareBytes(bytes, ShakeHandReq.content,ShakeHandReq.content.length)){
            // 如果与握手内容相同
            ZwCommPacket zwCommPacket = new ZwCommPacket(ActionConstants.shakeHandStr) {
                @Override
                public void convertToHexStr() {

                }

                @Override
                public void convertToProp() {

                }
            };
            out.add(zwCommPacket);
            return;
        }
        buf.resetReaderIndex();

        // peerId	    32bits无符号整型 4个字节
        //peerPackId	32bits无符号整型 4个字节
        //bufSize	    32bits无符号整型 4个字节
        //cmd	        16bits无符号短整型 2个字节
        //packProp	    8bits 1个字节
        //cmdProp	    8bits 1个字节
        int headerLen = 4 + 4 + 4 + 2 + 1 + 1;
        if (readableBytesLen < headerLen){
            log.error("readableBytesLen[{}]< header's len is error,return.",readableBytesLen);
            return;
        }
        buf.markReaderIndex();

        long peerId = buf.readUnsignedIntLE();
        long peerPackId = buf.readUnsignedIntLE();
        long bufSize = buf.readUnsignedIntLE();
        int cmd = buf.readUnsignedShortLE();
        short packProp = buf.readUnsignedByte();
        short cmdProp = buf.readUnsignedByte();

        // 剩余字节长度
        if (readableBytesLen-headerLen < bufSize){
            // 如果当前长度减去头部长度的值小于头部定义的包长度，则return
            log.error("readableBytesLen[{}]< bufSize[{}] is error,return.",readableBytesLen,bufSize);
            buf.resetReaderIndex();
            return;
        }
        byte[] buff = null;
        if (bufSize>0) {
            buff = new byte[(int) bufSize];
            buf.readBytes(buff);
//            log.info("buf.readBytes(bytes):{}", ByteUtils.byteToHex(buff));
        }

        ZwCommPacket zwCommPacket = new ZwCommPacket(ActionConstants.getByCommandVal((short) cmd).getActionName()) {
            @Override
            public void convertToHexStr() {

            }

            @Override
            public void convertToProp() {

            }
        };

        ZwCommPacketHead zwCommPacketHead = new ZwCommPacketHead();
        zwCommPacketHead.setPeerId((int) peerId);
        zwCommPacketHead.setPeerPackId((int) peerPackId);
        zwCommPacketHead.setCmd((short) cmd);
        zwCommPacketHead.setBufSize((int) bufSize);
        zwCommPacketHead.setPackProp((byte) packProp);
        zwCommPacketHead.setCmdProp((byte) cmdProp);

        zwCommPacket.setHead(zwCommPacketHead);
        if (buff!=null) {
            zwCommPacket.setBuff(buff);
        }

        out.add(zwCommPacket);
    }
}
